﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace AudiPyme.DAL
{
    public class ActivosEmpresaFactory
    {
        //Insertar un activo en la BD
        public static void InsertarActivo(ActivosEmpresa NuevoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToActivosEmpresaEstablecer(NuevoActivo);
            agenteBD.SaveChanges();
        }

        //Método que recoge el número de Activos actuales de una Empresa por Id Tipo de Activo
        public static int NumeroActivosTipoActivoEmpresa(int IdEmpresa, int IdTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NTipActivoEmp = (from TipoAct in agenteBD.ActivosEmpresaEstablecer
                                 where TipoAct.IdTipoActivo == IdTipoActivo &&
                                       TipoAct.IdEmpresa == IdEmpresa && TipoAct.Actual == true
                                 select TipoAct).Count();
            return NTipActivoEmp;
        }

        //Método que devuelve el número de activos actuales de una empresa
        public static int NumeroTotalesActivosEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NTipActivoEmp = (from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                 where ActEmp.IdEmpresa == IdEmpresa && ActEmp.Actual == true
                                 select ActEmp).Count();
            return NTipActivoEmp;
        }

        //Recoge los datos de la empresa para el Informe
        public static List<Puntos> ValoresEmpresaInforme(int IdEmpresa, int IdInforme)
        {
            List<Puntos> LPuntos = new List<Puntos>();
            List<String> AtributosEmpresa = new List<String>();
            //Ponemos los atributos a rellenar en la tabla
            AtributosEmpresa.Add("Nº total de Activos");
            AtributosEmpresa.Add("Nº total de Relaciones");
            AtributosEmpresa.Add("Nº Relaciones Tipo Activo - Amenaza");
            AtributosEmpresa.Add("Nº Relaciones Tipo Activo - Vulnerabilidad");
            List<int> ValoresAtributosEmp = new List<int>();
            int NumActivosEmp = ActivosInformeFactory.NumeroTotalesActivosEmpresaInforme(IdInforme);
            int NumRelTipActAmenCritEmp = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.NumRelacTipAmenCritEmpresaInforme(IdInforme);
            int NumRelTipActVuln = InstanciaTiposActivosVulnerabilidadesFactory.NumRelacTipActVulnInforme(IdInforme);
            int NumRelTotEmpresa = NumRelTipActAmenCritEmp + NumRelTipActVuln;
            ValoresAtributosEmp.Add(NumActivosEmp);
            ValoresAtributosEmp.Add(NumRelTotEmpresa);
            ValoresAtributosEmp.Add(NumRelTipActAmenCritEmp);
            ValoresAtributosEmp.Add(NumRelTipActVuln);
            for (int i = 0; i < ValoresAtributosEmp.Count(); i++)
            {
                Puntos nuevoPunto = new Puntos(AtributosEmpresa[i], ValoresAtributosEmp[i]);
                LPuntos.Add(nuevoPunto);
            }
            return LPuntos;
        }

        //Método que recoge los activos actuales de una empresa por Tipo de activo
        public static IQueryable<ActivosEmpresa> ActivosEmpresaTipoActivo(int IdEmpresa, int IdTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosEmpresa> ActivosEmpresa = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                                        where ActEmp.IdEmpresa == IdEmpresa && ActEmp.IdTipoActivo == IdTipoActivo &&
                                                        ActEmp.Actual == true
                                                        select ActEmp;
            return ActivosEmpresa;
        }

        //Método que recoge los tipos de activos de los activos que tiene actualmente una empresa
        public static List<int> ActivosEmpresaTipoActivo(int IdEmpresa)
        {
            List<int> LIdsTiposActivosEmpresa = new List<int>();
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosEmpresa> ActivosEmpresaQuery = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                                             where ActEmp.IdEmpresa == IdEmpresa && ActEmp.Actual == true
                                                             select ActEmp;
            foreach (ActivosEmpresa Activo in ActivosEmpresaQuery)
            {
                if (!LIdsTiposActivosEmpresa.Contains(Activo.IdTipoActivo))
                    LIdsTiposActivosEmpresa.Add(Activo.IdTipoActivo);
            }
            return LIdsTiposActivosEmpresa;
        }
        //Recoge los Activos Actuales de una empresa por Valor Estratégico
        public static IQueryable<ActivosEmpresa> ActivosEmpresaValorEstrategico(int IdEmpresa, int ValorEstrategico)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosEmpresa> ActivosEmpresa = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                                        where ActEmp.IdEmpresa == IdEmpresa && ActEmp.ValorEstrategico == ValorEstrategico &&
                                                        ActEmp.Actual == true
                                                        select ActEmp;
            return ActivosEmpresa;
        }

        //Método para probar que se recogen los activos de una empresa
        public static List<ActivosEmpresa> PruebaRecogeActivosEmpresa(int IdEmpresa)
        {
            List<ActivosEmpresa> ListaActivosEmpresa = new List<ActivosEmpresa>();
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosEmpresa> ActivosEmpresa = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                                        where ActEmp.IdEmpresa == IdEmpresa
                                                        select ActEmp;
            foreach (ActivosEmpresa Activo in ActivosEmpresa)
            {
                ListaActivosEmpresa.Add(new ActivosEmpresa(Activo.IdActivo, Activo.IdEmpresa, Activo.IdTipoActivo, Activo.Nombre, Activo.Descripcion, Activo.CosteActivo, Activo.ValorEstrategico, true));
            }
            return ListaActivosEmpresa;
        }

        //Método que recoge los Activos de una Empresa por Rangos de Coste (€)
        public static IQueryable<ActivosEmpresa> ActivosEmpresaCosteActivo(int IdEmpresa, List<int> Rangos, int RangoElegido)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Si el Rango elegido es superior al millón de €
            if (RangoElegido.Equals(1000001))
            {
                IQueryable<ActivosEmpresa> ActivosEmpresa = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                                            where ActEmp.IdEmpresa == IdEmpresa
                                                                  && ActEmp.CosteActivo >= RangoElegido && ActEmp.Actual == true
                                                            select ActEmp;

                return ActivosEmpresa;
            }
            else
            {
                int indiceRangoElegido = Rangos.IndexOf(RangoElegido);
                int RangoAnterior = 0;
                if (indiceRangoElegido != 0)
                {
                    RangoAnterior = Rangos[indiceRangoElegido - 1];
                }
                IQueryable<ActivosEmpresa> ActivosEmpresa = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                                            where ActEmp.IdEmpresa == IdEmpresa && ActEmp.CosteActivo <= RangoElegido
                                                                  && ActEmp.CosteActivo > RangoAnterior && ActEmp.Actual == true
                                                            select ActEmp;

                return ActivosEmpresa;
            }
        }

        //Método que actualiza los valores de un activo actual de una empresa
        public static void ActualizarActivoEmpresa(int IdEmpresa, int IdActivo, String NombreActivo, int CosteActivo, int ValorEstrategico)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var ActivoEmpresa = (from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                 where ActEmp.IdActivo == IdActivo && ActEmp.IdEmpresa == IdEmpresa && ActEmp.Actual == true
                                 select ActEmp).Single();
            ActivoEmpresa.Nombre = NombreActivo;
            ActivoEmpresa.CosteActivo = CosteActivo;
            ActivoEmpresa.ValorEstrategico = ValorEstrategico;
            agenteBD.SaveChanges();
        }

        //Método que recoge la lista de Número de Activos actuales de una empresa por su Valor (Bajo, Medio, Alto)
        public static List<int> ActivosEmpresaPorValor(int IdEmpresa)
        {
            List<int> LActivosValor = new List<int>();
            ModeloContainer agenteBD = new ModeloContainer();
            int NumeroValores = 3;
            for (int i = 0; i < NumeroValores; i++)
            {
                //Los valores posibles de Valor Activo van del 1 al 3 por eso llamamos con el contador i aumentado en 1
                int ValorActivo = i + 1;
                int NumActValor = NumActivosEmpresaValor(IdEmpresa, ValorActivo);
                LActivosValor.Insert(i, NumActValor);
            }
            return LActivosValor;
        }

        //Devuelve el número de Activos actuales de una empresa con un id de valor de activo dado (Bajo, Medio, Alto)
        private static int NumActivosEmpresaValor(int IdEmpresa, int ValorActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int ActivosValorBajo = (from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                    where ActEmp.ValorEstrategico == ValorActivo && ActEmp.IdEmpresa == IdEmpresa &&
                                    ActEmp.Actual == true
                                    select ActEmp).Count();
            return ActivosValorBajo;
        }

        //Devuelve una lista con los posibles valores de ValorEstratégico
        public static List<String> TiposValorEstrategico()
        {
            List<String> TiposValores = new List<String>(3);
            TiposValores.Add("Bajo");
            TiposValores.Add("Medio");
            TiposValores.Add("Alto");
            return TiposValores;
        }

        //Método que serializa el atributo de valor estratégico
        public static int RecogeIdValorEstrategico(String ValorEstrategico)
        {
            //Valor centinela
            int IdValorEstrategico = -1;
            switch (ValorEstrategico)
            {
                case "Bajo":
                    IdValorEstrategico = 1;
                    break;
                case "Medio":
                    IdValorEstrategico = 2;
                    break;
                case "Alto":
                    IdValorEstrategico = 3;
                    break;
            }
            return IdValorEstrategico;
        }

        //Método que deserializa los valores de Valor Estratégico
        public static String RecogeValorEstrategico(int IdValorEstrategico)
        {
            String ValorEstrategico = "";
            switch (IdValorEstrategico)
            {
                case 1:
                    ValorEstrategico = "Bajo";
                    break;
                case 2:
                    ValorEstrategico = "Medio";
                    break;
                case 3:
                    ValorEstrategico = "Alto";
                    break;
                default:
                    break;
            }
            return ValorEstrategico;
        }

        //Método para formatear los rangos
        public static List<String> RecogeRangos(List<int> Rangos)
        {
            List<String> ValoresRangos = new List<String>();
            for (int i = 0; i < Rangos.Count && Rangos[i] != 0; i++)
            {
                if (i != (Rangos.Count - 1))
                {
                    String Rango = "< " + Rangos[i].ToString() + " €";
                    ValoresRangos.Insert(i, Rango);
                }
                else
                {
                    String Rango = "> " + Rangos[i].ToString() + " €";
                    ValoresRangos.Insert(i, Rango);
                }
            }
            return ValoresRangos;
        }

        //Método que elimina (borrado lógico) un activo asociado a una empresa
        public static void EliminarActivosEmpresa(int IdActivo, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            ActivosEmpresa nuevoActivo = new ActivosEmpresa();
            nuevoActivo.IdEmpresa = IdEmpresa;
            nuevoActivo.IdActivo = IdActivo;
            ActivosEmpresa ActivoEliminar = (from ActivoEmp in agenteBD.ActivosEmpresaEstablecer
                                             where ActivoEmp.IdActivo == nuevoActivo.IdActivo &&
                                                   ActivoEmp.IdEmpresa == nuevoActivo.IdEmpresa && ActivoEmp.Actual == true
                                             select ActivoEmp).First();
            ActivoEliminar.Actual = false;
            agenteBD.SaveChanges();
        }

        //Devuelve el nombre de un activo a través de su identificador
        public static String NombreActivo(int IdActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> nombreActivo = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                              where ActEmp.IdActivo == IdActivo
                                              select ActEmp.Nombre;
            if (nombreActivo.Count() == 0)
            {
                return "";
            }
            return nombreActivo.First();
        }

        //Devuelve el coste de un activo a través de su identificador
        public static int CosteActivo(int IdActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> costeAct = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                       where ActEmp.IdActivo == IdActivo
                                       select ActEmp.CosteActivo;
            if (costeAct.Count() == 0)
            {
                return -1;
            }
            return costeAct.First();
        }

        //Método que devuelve el valor estrategico de un activo
        public static int ValorEstrategicoActivo(int IdActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int ValorEstrategico = 0;
            IQueryable<int> ValorEstrat = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                          where ActEmp.IdActivo == IdActivo
                                          select ActEmp.ValorEstrategico;
            if (ValorEstrat.Count() != 0)
            {
                ValorEstrategico = ValorEstrat.First();
            }
            return ValorEstrategico;
        }

        //Método que elimina de forma física todas los activos asociados a una empresa
        internal static void EliminaTotalActivos(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosEmpresa> ActivosEliminarQuery = from ActEmp in agenteBD.ActivosEmpresaEstablecer
                                                              where ActEmp.IdEmpresa == IdEmpresa
                                                              select ActEmp;
            if (ActivosEliminarQuery.Count() != 0)
            {
                foreach (ActivosEmpresa Activo in ActivosEliminarQuery)
                {
                    agenteBD.ActivosEmpresaEstablecer.DeleteObject(Activo);
                }
                agenteBD.SaveChanges();
            }
        }

        //Devuelve el Nombre de un Tipo Activo a través del Id del Activo
        public static string NombreTipoActivoActivo(int IdActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> TipAct = from Act in agenteBD.ActivosEmpresaEstablecer
                                        join TA in agenteBD.TiposActivosEstablecer on Act.IdTipoActivo equals TA.IdTipoActivo
                                        where Act.IdActivo == IdActivo
                                        select TA.TipoActivo;
            if (TipAct.Count() == 0)
                return "";
            else
                return TipAct.First();
        }

        //Devuelve la Descripción de un Activo
        public static string DescripcionActivo(int IdActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> DescrAct = from Act in agenteBD.ActivosEmpresaEstablecer
                                          where Act.IdActivo == IdActivo
                                          select Act.Descripcion;
            if (DescrAct.Count() == 0)
                return "";
            else
                return DescrAct.First();
        }

        //Devuelve el IdTipoActivo de un Activo
        internal static int IdTipoActivoActivo(int IdActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> DescrAct = from Act in agenteBD.ActivosEmpresaEstablecer
                                       where Act.IdActivo == IdActivo
                                       select Act.IdTipoActivo;
            if (DescrAct.Count() == 0)
                return 0;
            else
                return DescrAct.First();
        }

        //Método que recoge los activos que están declarados actualmente en una empresa
        public static List<ActivosEmpresa> ActivosActuales(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<ActivosEmpresa> LActivos = new List<ActivosEmpresa>();
            IQueryable<ActivosEmpresa> ActivosTotEmpresaQuery = from ActivEmp in agenteBD.ActivosEmpresaEstablecer
                                                                where ActivEmp.IdEmpresa == IdEmpresa && ActivEmp.Actual == true
                                                                select ActivEmp;
            if (ActivosTotEmpresaQuery.Count() != 0)
            {
                LActivos = ActivosTotEmpresaQuery.ToList();
            }
            return LActivos;
        }

        //Método que devuelve los activos de una empresa cuyo nombre de activo coincide con el patrón de textobuscar seleccionado
        public static IQueryable<ActivosEmpresa> ActivosEmpresaPorNombre(String TextoBuscar, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosEmpresa> LActivos = (from a in agenteBD.ActivosEmpresaEstablecer
                                                   join t in agenteBD.TiposActivosEstablecer on a.IdTipoActivo equals t.IdTipoActivo
                                                   where a.IdEmpresa == IdEmpresa && a.Actual == true && a.Nombre.Contains(TextoBuscar)
                                                   select a).Distinct().OrderBy(i => i.IdActivo);
            return LActivos;
        }

        //Método que devuelve los activos de una empresa cuyos tipos de activos coinciden con el patrón de textobuscar seleccionado
        public static IQueryable<ActivosEmpresa> ActivosEmpresaPorTipoActivo(String TextoBuscar, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ActivosEmpresa> LActivos = (from a in agenteBD.ActivosEmpresaEstablecer
                                                   join t in agenteBD.TiposActivosEstablecer on a.IdTipoActivo equals t.IdTipoActivo
                                                   where a.IdEmpresa == IdEmpresa && a.Actual == true && t.TipoActivo.Contains(TextoBuscar)
                                                   select a).Distinct().OrderBy(i => i.IdActivo);
            return LActivos;
        }


    }

    //Clase para formatear los valores de los activos en elementos que puedan mostrarse en gráfico de barras
    public class Puntos
    {
        String x;
        int y;

        public Puntos(String X, int Y)
        {
            x = X;
            y = Y;
        }

        public Puntos()
        {

        }

        public String X
        {
            get { return x; }
            set { x = value; }
        }

        public int Y
        {
            get { return y; }
            set { y = value; }
        }

    }
}
